// axios的封装处理
import axios from 'axios';

//1、根域名配置
//2、超时时间
//3、请求拦截器/响应拦截器

// const request = axios.create({
//   baseURL: 'http://geek.itheima.net/v1_0',
//   timeout: 5000,
//   // headers: { 'X-Custom-Header': 'foobar' }
// });

// // 添加请求拦截器{插入一些自定义的配置【参数的处理】}
// request.interceptors.request.use((config) => {
//   // 在发送请求之前做些什么
//   return config;
// }, (error) => {
//   // 对请求错误做些什么
//   return Promise.reject(error);
// });

// // 添加响应拦截器
// //在响应返回到客户端之前做拦截【重点处理返回的数据】
// request.interceptors.response.use((response) => {
//   // 对响应数据做点什么
//   return response;
// }, (error) => {
//   // 对响应错误做点什么
//   return Promise.reject(error);
// });

// // export default request;
// export { request }


class Request {
  constructor(rootConfig) {
    this.service = axios.create(rootConfig); // 创建实例
    this.interceptors = rootConfig.interceptors; // 每个实例特有的拦截
    this.mockBaseURL = rootConfig.mockBaseURL; // mock地址

    if (rootConfig.useGlobalMock && rootConfig.mockBaseURL) {
      this.mockBaseURL = rootConfig.mockBaseURL;
    }
    // 每个实例都有的拦截器，可以在这里统一处理
    // 1.全局请求拦截
    this.service.interceptors.request.use(
      (config) => {
        // 请求拦截成功
        return config;
      },
      (_) => {
        // 请求拦截失败
        console.log(_);
        return;
      }
    );

    // 2.全局响应拦截
    this.service.interceptors.response.use(
      (res) => {
        // 响应成功的拦截
        return this.isAxiosResponse(res) ? res.data : res;
      },
      (err) => {
        // 响应失败的拦截
        console.log(err);
        return err;
      }
    );

    // 每个实例特有的请求拦截
    if (this.interceptors && this.interceptors.requestInterceptor) {
      this.service.interceptors.request.use(
        this.interceptors.requestInterceptor,
        this.interceptors.requestInterceptorCatch
      );
    }

    // 每个实例特有的响应拦截
    if (this.interceptors && this.interceptors.responseInterceptor) {
      this.service.interceptors.response.use(
        this.interceptors.responseInterceptor,
        this.interceptors.responseInterceptorCatch
      );
    }
  }


  // 主要是这个方法发送请求的
  request(config) {
    // 这个可以处理mock请求 不用管
    const originBaseURL = this.service.defaults.baseURL;
    if (config.useMock && this.mockBaseURL) {
      this.service.defaults.baseURL = this.mockBaseURL;
    }

    return new Promise((resolve, reject) => {
      // 单个请求的请求拦截器
      if (config.interceptors && config.interceptors.requestInterceptor) {
        this.service.interceptors.request.use(
          config.interceptors.requestInterceptor,
          config.interceptors.requestInterceptorCatch
        );
      }

      // 单个请求的响应拦截器
      if (config.interceptors && config.interceptors.responseInterceptor) {
        this.service.interceptors.response.use(
          config.interceptors.responseInterceptor,
          config.interceptors.responseInterceptorCatch
        );
      }

      // 发请求在这里 核心就这几个
      // 整体主要是用到了多个拦截器
      // 类拦截器 == 每个实例都有的拦截器
      // 单个拦截器 = 每个实例特有的拦截器
      this.service
        .request(config)
        .then((res) => {
          resolve(res);
        })
        .catch((err) => {
          reject(err);
        })
        .finally(() => {
          // 这个也不用管 用mock的时候才有用
          this.service.defaults.baseURL = originBaseURL;
        });
    });
  }

  get(config) {
    return this.request({ ...config, method: 'GET' });
  }

  post(config) {
    return this.request({ ...config, method: 'POST' });
  }

  delete(config) {
    return this.request({ ...config, method: 'DELETE' });
  }

  patch(config) {
    return this.request({ ...config, method: 'PATCH' });
  }

  put(config) {
    return this.request({ ...config, method: 'PUT' });
  }

  isAxiosResponse(res) {
    return (
      res.config &&
      res.data &&
      res.status &&
      res.statusText &&
      res.headers &&
      res.request
    );
  }
}

export default Request;